package seedpod.kb2db;
/**
 * Copyright 2009 University of  Washington
 * This code is released under the GPL version 3 - with a copy of the license included
 * @author Maya Hao Li
 *
 */
/**
 * <p>
 * Title: KnowldgeBase to Database
 * </p>
 * <p>
 * Description: Writes the RDB schema to in SQL format
 * </p>
 * <p>
 * Copyright: Copyright (c) 2002
 * </p>
 * <p>
 * Company: University of Washington BHI
 * </p>
 * 
 * @author Hao Li
 * @version 2.0
 */
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Vector;

import seedpod.model.rdb.Rdb;
import seedpod.model.rdb.Relation;
import seedpod.model.rdb.SimpleForeignKey;
import seedpod.model.rdb.View;
import seedpod.model.rdb.ViewReference;
import seedpod.rdb.RdbSql;

public class RdbSchemaWriter {
	protected Rdb _rdb;
	protected StringBuffer _sql;
	protected StringBuffer _cleanup;

	public RdbSchemaWriter(Rdb rdb) {
		_rdb = rdb;
		_sql = new StringBuffer();
		_cleanup = new StringBuffer();
	}

	/**
	 * writes out a generic XML document for the RDB
	 * 
	 * @param out
	 * @return
	 * @throws KBtoDB.XMLWriter.XMLException
	 */
	public void serializeRDB() throws IOException {
		Vector<Relation> relations = _rdb.getRelations();
		Vector<SimpleForeignKey> foriegnKeys = _rdb.getForeignKeys();
		Vector<View> views = _rdb.getViews();
		Vector<ViewReference> viewReferences = _rdb.getViewKeys();

		// _sql.append( RdbSql.createDB( _rdb ) );

		// serialize tables
		Iterator<Relation> relItr = relations.iterator();
		Relation rel;
		while (relItr.hasNext()) {
			rel = (Relation)relItr.next();
			_sql.append( RdbSql.createTable( rel ) ); // serializeRelation( rel );
		}

		// foreign keys
		Iterator<SimpleForeignKey> keyItr = foriegnKeys.iterator();
		SimpleForeignKey fk;
		int fkCount = 0;
		while (keyItr.hasNext()) {
			fk = (SimpleForeignKey)keyItr.next();
			_sql.append( RdbSql.createForeignKey( fk ) );
			fkCount++;
		}

		// views
		Iterator<View> viewItr = views.iterator();
		View view;
		while (viewItr.hasNext()) {
			view = (View)viewItr.next();
			_sql.append( RdbSql.createView( view ) );
		}

		// view references or rules
		Iterator<ViewReference> viewRefItr = viewReferences.iterator();
		ViewReference vk;
		int vkCount = 0;
		while (viewRefItr.hasNext()) {
			vk = (ViewReference)viewRefItr.next();
			_sql.append( RdbSql.createViewReference( vk ) );
			vkCount++;
		}

	}

	public void cleanupRDB() throws IOException {
		Vector<Relation> relations = _rdb.getRelations();
		Vector<View> views = _rdb.getViews();

		// drop table statements
		Iterator<Relation> relItr = relations.iterator();
		Relation rel;
		while (relItr.hasNext()) {
			rel = (Relation)relItr.next();
			_cleanup.append( RdbSql.dropTable( rel ) );
		}

		// drop view statements
		Iterator<View> viewItr = views.iterator();
		View view;
		while (viewItr.hasNext()) {
			view = (View)viewItr.next();
			_cleanup.append( RdbSql.dropView( view ) );
		}
	}

	public void serialize( PrintStream ostream ) throws IOException {
		serializeRDB();
		ostream.println( _sql );
	}

	public void serialize( PrintWriter writer ) throws IOException {
		serializeRDB();
		writer.write( _sql.toString() );
	}

	public void serialize( PrintWriter writer, boolean cleanRDB ) throws IOException {
		if ( cleanRDB )
			cleanupRDB();
		writer.write( _sql.toString() );
	}

}